package dparish.client.view.impl;

import java.util.Comparator;
import java.util.List;

import javax.inject.Singleton;

import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.NumberCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.user.cellview.client.IdentityColumn;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;

import dparish.client.proxy.StudentProxy;
import dparish.client.view.StudentListView;
import dparish.shared.StringUtil;

/**
 * Implementation class for the view of multiple students.
 * @author dparish
 */
@Singleton
public class StudentListViewImpl extends Composite implements StudentListView {

	private static StudentListViewImplUiBinder uiBinder = GWT
			.create(StudentListViewImplUiBinder.class);

	private ListDataProvider<StudentProxy> students = new ListDataProvider<StudentProxy>();
	private StudentListView.Presenter<StudentProxy> presenter = null;
	private StudentMessages studentMessages = GWT.create(StudentMessages.class);
	
	// The columns for the table.
	TextColumn<StudentProxy> idColumn = null;
	TextColumn<StudentProxy> firstNameColumn = null;
	TextColumn<StudentProxy> lastNameColumn = null;
	TextColumn<StudentProxy> emailColumn = null;
	
	@UiField CellTable<StudentProxy> studentsTable;
	@UiField Button addStudentButton;
	@UiField Label locale;
	@UiField Label countMessage;
	
	@UiTemplate ("StudentListView.ui.xml")
	interface StudentListViewImplUiBinder extends
			UiBinder<Widget, StudentListViewImpl> {
	}

	public StudentListViewImpl() {
		initWidget(uiBinder.createAndBindUi(this));
		initTable();
	}
	
	private void initTable() {
		// hook the data provider to the table
		students.addDataDisplay(studentsTable);
		
		// Add each of the columns.
		
		// idColumn
		idColumn = new TextColumn<StudentProxy>() {
			@Override
			public String getValue(StudentProxy student) {
				return student.getId() + "";
			}
		};
		idColumn.setSortable(true);
		studentsTable.addColumn(idColumn, "ID");
		
		// firstNameColumn
		firstNameColumn = new TextColumn<StudentProxy>() {
			@Override
			public String getValue(StudentProxy student) {
				return student.getFirstName();
			}
		};
		firstNameColumn.setSortable(true);
		studentsTable.addColumn(firstNameColumn,"First Name");
		
		// lastNameColumn
		lastNameColumn = new TextColumn<StudentProxy>() {
			@Override
			public String getValue(StudentProxy student) {
				return student.getLastName();
			}
		};
		lastNameColumn.setSortable(true);
		studentsTable.addColumn(lastNameColumn, "Last Name");
		
		// emailColumn
		emailColumn = new TextColumn<StudentProxy>() {
			@Override
			public String getValue(StudentProxy student) {
				return student.getEmail();
			}
		};
		emailColumn.setSortable(true);
		studentsTable.addColumn(emailColumn, "Email");
		
		// Add a selection handler
		final SingleSelectionModel<StudentProxy> selectionModel = new SingleSelectionModel<StudentProxy>();
		studentsTable.setSelectionModel(selectionModel);
		
		selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
			
			@Override
			public void onSelectionChange(SelectionChangeEvent event) {
				StudentProxy selectedStudent = selectionModel.getSelectedObject();
				presenter.onSelectedEvent(selectedStudent);
			}
		});
		
		// make table sortable
		studentsTable.addColumnSortHandler(getSortHandler());
		studentsTable.getColumnSortList().push(lastNameColumn);
	}
	
	/**
	 * Build a sort handler that can handle and understand the sortable columns.
	 * I hesitated adding this as it adds complexity to the example code, but it also shows the flexibility of CellTable
	 * @return
	 * @see <a href="http://code.google.com/webtoolkit/doc/latest/DevGuideUiCellTable.html">Developer's Guide - Cell Table</a>
	 */
	private ColumnSortEvent.ListHandler<StudentProxy> getSortHandler() {
		ColumnSortEvent.ListHandler<StudentProxy> studentSortHandler  = new ColumnSortEvent.ListHandler<StudentProxy>(students.getList());
		studentSortHandler.setComparator(idColumn, new Comparator<StudentProxy>() {
			@Override
			public int compare(StudentProxy o1, StudentProxy o2) {
				return o1.getId().compareTo(o2.getId());
			}
		});
		studentSortHandler.setComparator(firstNameColumn, new Comparator<StudentProxy>() {
			@Override
			public int compare(StudentProxy o1, StudentProxy o2) {
				return StringUtil.stringCompare(o1.getFirstName(), o2.getFirstName());
			}
		});
		studentSortHandler.setComparator(lastNameColumn, new Comparator<StudentProxy>() {
			@Override
			public int compare(StudentProxy o1, StudentProxy o2) {
				return StringUtil.stringCompare(o1.getLastName(), o2.getLastName());
			}
		});
		studentSortHandler.setComparator(emailColumn, new Comparator<StudentProxy>() {
			@Override
			public int compare(StudentProxy o1, StudentProxy o2) {
				return StringUtil.stringCompare(o1.getEmail(), o2.getEmail());
			}
		});

		return studentSortHandler;

	}
	
	
	@UiHandler ("addStudentButton")
	public void handleAddStudentClick (ClickEvent evt) {
		presenter.onAddEvent();
	}

	public void setPresenter(StudentListView.Presenter<StudentProxy> p) {
		this.presenter = p;
	}

	@Override
	public void render() {
		// You would think I could call: students.setList(presenter.getEntities());  If you do, the column sorting won't work see:
		// http://code.google.com/p/google-web-toolkit/issues/detail?id=6686
		students.getList().clear();
		students.getList().addAll(presenter.getEntities());
		locale.setText(LocaleInfo.getCurrentLocale().getLocaleName());
		countMessage.setText(studentMessages.studentCount(presenter.getEntities().size()));
		
		
		// Fire the column sort event so the table is sorted with the new data.
		ColumnSortEvent.fire(studentsTable, studentsTable.getColumnSortList());
		
	}


	@Override
	public void loadCallback(String message) {
		if (message != null) {
			Window.alert("Failure getting the list of students:" + message);
		}
	}

}

